<template>
  <div class="menu-modal">
    <a-modal
      v-if="visible"
      width="800px"
      :title="modalTitle"
      :visible="visible"
      :confirm-loading="confirmLoading"
      :destroy-on-close="true"
      @ok="handleSubmitClick"
      @cancel="resetFormModalData"
    >
      <a-form-model
        ref="formRef"
        :model="form"
        :rules="formRules"
        layout="vertical"
      >
        <a-row :gutter="24">
          <a-col :span="12">
            <a-form-model-item
              label="菜单名称"
              prop="menuName"
            >
              <a-input
                v-model="form.menuName"
                placeholder="请输入菜单名称"
              />
            </a-form-model-item>
            <a-form-model-item
              label="菜单类型"
              prop="menuType"
            >
              <a-select
                :disabled="modalData.type === 'EDIT'"
                :showSearch="true"
                :allowClear="true"
                placeholder="请选择菜单类型"
                :filterOption="filterSelectOption"
                v-model="form.menuType"
              >
                <a-select-option :value="'1'" :disabled="selectedTreeItemData.menuType === '2'">
                  文件夹
                </a-select-option>
                <a-select-option :value="'2'" :disabled="selectedTreeItemData.menuType === '2'">
                  菜单
                </a-select-option>
                <a-select-option :value="'3'" :disabled="selectedTreeItemData.menuType === '1'">
                  按钮
                </a-select-option>
              </a-select>
            </a-form-model-item>
            <a-form-model-item
              v-if="form.menuType === '2'"
              label="URL"
              prop="url"
            >
              <a-input
                v-model="form.url"
                placeholder="请注意格式，禁止空格 eg: 'user/user-list'"
              />
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="当前上级菜单">
              <a-tree
                :key="treeKey"
                :replaceFields="replaceFields"
                :selected-keys="selectedKeys"
                :tree-data="treeData"
                :defaultExpandAll="true"
                :showLine="true"
                @select="handleTreeSelect"
              />
            </a-form-model-item>
          </a-col>
        </a-row>
      </a-form-model>
    </a-modal>
  </div>
</template>

<script>
import menuApi from '@/api/menu';
import emitter from '@/utils/emitter';
import Events from '@/utils/event';
import { get } from 'lodash-es';

const menuOption = [
  {
    text: '文件夹',
    value: '1'
  },
  {
    text: '菜单',
    value: '2'
  }
];

export default {
  name: 'MenuModal',
  props: {
    modalData: {
      type: Object
    }
  },
  data () {
    const validateUrl = (rule, value, callback) => {
      const reg1 = /^[/A-Za-z0-9_-]+$/;
      const reg2 = /^[A-Za-z]+$/;
      const reg3 = /^[A-Za-z0-9]+$/;
      if (!reg1.test(value)) {
        callback(new Error('URL格式错误'));
      } else if (!reg2.test(value.substr(0, 1))) { // 第一个字符只能是英文
        callback(new Error('首个字符必须是英文'));
      } else if (!reg3.test(value.substr(-1))) {
        callback(new Error('末尾字符必须是英文或数字'));
      } else {
        callback();
      }
    };
    return {
      menuOption,
      treeKey: 1,
      treeData: [],
      selectedKeys: [],
      selectedTreeItemData: {},
      replaceFields: {
        title: 'menuName',
        key: 'id',
        children: 'children'
      },
      form: {
        menuName: '',
        menuType: undefined,
        url: ''
      },
      formRules: {
        menuName: {
          required: true,
          message: '请输入菜单名称',
          trigger: 'blur'
        },
        menuType: {
          required: true,
          message: '请选择菜单类型',
          trigger: 'change'
        },
        url: {
          required: true,
          validator: validateUrl,
          trigger: 'blur'
        }
      },
      isMenuTypeDisabled: false,
      modalTitle: '',
      visible: false,
      confirmLoading: false
    };
  },
  methods: {
    // 用于 select 搜索
    filterSelectOption (value, option) {
      return option.componentOptions.children[0].text.indexOf(value) >= 0;
    },
    handleTreeSelect (selectedKeys, info) {
      if (selectedKeys.length) {
        this.setSelectedTreeItemData(this.treeData, selectedKeys[0]);
        if (this.modalData.type === 'EDIT') {
          return this.$message.error('编辑状态下，不能更换上级菜单');
        }
        if (this.modalData.type === 'ADD' && this.selectedTreeItemData.icon === 'button') {
          return this.$message.error('新增状态下，当前菜单不能作为上级菜单');
        }
        this.selectedKeys = selectedKeys;
        this.form.menuType = undefined;
      }
    },
    setSelectedTreeItemData (list, id) {
      for (let i = 0; i < list.length; i++) {
        const item = list[i];
        // 找到目标
        if (item.id === id) {
          this.selectedTreeItemData = item;
        }
        // 如果存在下级节点，则继续遍历
        if (item.children && item.children.length) {
          this.setSelectedTreeItemData(item.children, id);
        }
      }
    },
    handleSubmitClick () {
      this.confirmLoading = true;
      this.$refs.formRef.validate(valid => {
        if (valid) {
          if (this.form.id) {
            this.updateDataAction();
          } else {
            this.createDataAction();
          }
        } else {
          this.confirmLoading = false;
          return false;
        }
      });
    },
    createDataAction () {
      menuApi.add({
        ...this.form,
        parentId: this.selectedKeys[0]
      }).then(res => {
        this.$message.success(res.msg);
        this.visible = false;
        this.resetFormModalData();
        emitter.emit(Events.REFRESH_TABLE, false);
      }).catch(e => {
        this.$message.error(e.msg);
      }).finally(() => {
        this.confirmLoading = false;
      });
    },
    updateDataAction () {
      menuApi.update({
        ...this.form,
        parentId: this.selectedKeys[0]
      }).then(res => {
        this.$message.success(res.msg);
        this.resetFormModalData();
        emitter.emit(Events.REFRESH_TABLE, false);
      }).catch(e => {
        this.$message.error(e.msg);
      }).finally(() => {
        this.confirmLoading = false;
      });
    },
    resetFormModalData () {
      this.visible = false;
      this.confirmLoading = false;
      this.treeData = [];
      this.form = {
        menuName: '',
        menuType: undefined,
        url: ''
      };
      this.selectedTreeItemData = {};
    },
    // 显示 modal
    showModal ({
      type,
      record
    }) {
      menuApi.list().then(res => {
        this.treeData = [
          {
            id: 0,
            url: '',
            menuName: 'Root',
            icon: 'folder',
            menuType: '1',
            children: res.result.rows || []
          }
        ];
        this.treeKey++;
        const {
          id,
          menuType,
          parentId,
          menuName,
          url
        } = record;
        if (type === 'EDIT') {
          this.modalTitle = '编辑';
          this.form = {
            id,
            menuName,
            menuType,
            url
          };
          this.isMenuTypeDisabled = true;
          this.selectedKeys = [parentId || 0];
          console.log(this.$data);
        } else if (type === 'ADD') {
          this.modalTitle = '新增';
          this.selectedKeys = [id || 0];
        }
      });
      this.visible = true;
    }
  },
  created () {
  },
  watch: {
    form: {
      deep: true,
      handler (newVal) {
        if (newVal.menuType !== '2') {
          this.form.url = '';
        }
      }
    },
    modalData: {
      deep: true,
      handler (newVal) {
        this.showModal(newVal);
        get(newVal, 'record.id')
          ? this.selectedTreeItemData = newVal.record
          : this.selectedTreeItemData = { menuType: '1' };
      }
    }
  }
};
</script>

<style scoped>

</style>
